package auctionServer.network;

import auctionServer.businessLogic.Peer;
import auctionServer.io.IOManager;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.util.StringTokenizer;

import auctionServer.AuctionServer;

public class ConnectionHandler implements Runnable{

	private AuctionServer auctionServer;
	private Socket socket;
	private Peer peer;

	public ConnectionHandler(AuctionServer auctionServer, Socket socket) {
		this.auctionServer = auctionServer;
		this.socket = socket;
	}
	
	public void run() {
		String line=null;
		BufferedReader input;
		try {//connect to server
			input = new BufferedReader(new InputStreamReader(socket.getInputStream() ));
			
			line = input.readLine();
			StringTokenizer tokens = new StringTokenizer(line," ");
			if(tokens.nextToken().equals("!createConnection")){
                int udpPortNumber = Integer.parseInt(tokens.nextToken());
                String serverAddress = socket.getInetAddress().getHostAddress();

                peer = new Peer(udpPortNumber, serverAddress);
			}
            else{
                terminate();
                return;
            }

			
			while(true){
				line = input.readLine();
				tokens = new StringTokenizer(line," ");

				
				String command = tokens.nextToken();

                if(command.equals("!login")){

                    if(peer.isLogin()){
                        peer.sendMessage("You have to logout first!");
                    }
                    else{
                        String nick = tokens.nextToken();
                        int udpPortNumber = peer.getPort();
                        String serverAddress = peer.getServerAddress();

                        for (Peer peer : auctionServer.getOfflinePeers()) {
                            if(peer.getNick().equals(nick)){
                                this.peer = peer;
                                auctionServer.getOfflinePeers().remove(peer);
                                peer.newConnect(udpPortNumber, serverAddress);
                                break;
                            }
                        }
                        peer.setNick(nick);
                        peer.sendMessage("Successfully logged in as "+peer.getNick()+"!");
                        peer.joined();
                    }
                }
                else if(command.equals("!list")){
                    String list = auctionServer.getItemManager().getList();
                    peer.sendMessage(list);
                }
                else if(!peer.isLogin()){
                    peer.sendMessage("You have to login first!");
                }
				else if(command.equals("!logout")){
					peer.sendMessage("Successfully logged out as "+peer.getNick()+"!");
					peer.sendMessage("!logout");
                    peer.logout();
					break;
				}
				else if(command.equals("!create")){
					int duration = Integer.parseInt(tokens.nextToken());
					String description = "";
					while(tokens.hasMoreTokens())
						description += " " +tokens.nextToken();
					description = description.substring(1);
					auctionServer.getItemManager().createItem(peer, duration, description);
				}
				else if(command.equals("!bid")){
					int id = Integer.parseInt(tokens.nextToken());
					int amount = Integer.parseInt(tokens.nextToken());
					auctionServer.getItemManager().bid(peer, id, amount);
				}
                else{
                    peer.sendMessage("Unknown command");
                }
			}
			
		} catch (Exception e) {
			//if here terminate() has already executed
			return;
		}

		terminate();
	}

	public void terminate() {
		try {
			socket.close();
		} catch (IOException e) {
			IOManager.addNotify("Error while closing client connection");
		}

        if(peer != null){
		    peer.stop();
		    peer.leaved();
        }

		auctionServer.leaveClient(this);
	}

	public Peer getPeer() {
		return peer;
	}

}
